使用者主要是透過 Touch 來跟 Mobile App 互動,跟網頁中的 Click 不太一樣。而它又可以結合各種的手勢,長按一個按鈕、滾動 List、放大縮小地圖、Swipe 等等,這邊會簡單介紹到一些相關的 Component。
React Native 內建許多能處理 Touch 的 Component (統稱 Touchables*),它們都能指定 onPress
、onPressIn
、onPressOut
、onLongPress
等等的 Event Handler,而它們之間的差別在於它們被 Touch 之後會有不同的回饋 (Feedback):
TouchableNativeFeedback
只有 Android 能用,而官方也不建議使用 TouchableWithoutFeedback
(完全沒有回饋),所以這兩個就先不介紹了。
TouchableHighlight
在被 Touch 之後會有一個 Highlight 的效果,而 Highlight 的顏色可以透過 underlayColor
改變。
<TouchableHighlight
onPress={() => {}}
underlayColor="red"
>
<View style={styles.btn}>
<Text style={styles.text}>按鈕</Text>
</View>
</TouchableHighlight>
更詳細的內容請參閱 TouchableHighlight
的官方文件。
TouchableOpacity
在被 Touch 之後會有一個透明度改變的效果。
<TouchableOpacity
onPress={() => {}}
>
<View style={styles.btn}>
<Text style={styles.text}>按鈕</Text>
</View>
</TouchableOpacity>
更詳細的內容請參閱 TouchableOpacity
的官方文件。
Button
是在v0.37.0
才導入的新 Component,React Naitve 部落格的這篇文章:Introducing Button, Faster Installs with Yarn, and a Public Roadmap 有介紹了它的由來,以往要做出一個跨平台可用的按鈕不夠簡單,而這是 React Native 未來的方向之一,所以才有了它。
<Button
onPress={() => {}}
title="按我啊"
accessibilityLabel="按我啊"
color="red"
disabled={false}
/>
為了簡單明瞭、立即可用,Button
的 API 做出了一些取捨:
onPress
,沒有 onPressIn
、onLongPress
等等的其他 Handlercolor
(在 iOS 是文字顏色、在 Android 是背景顏色) 的客製化,無法設定其他 style
更詳細的內容請參閱 Button
的官方文件。
內容超出一個畫面所能顯示的量時,我們通常需要使用 ScrollView
,讓它能藉由往下滑來瀏覽:
<ScrollView>
<Text style={{ fontSize: 60 }}>帶給各位滿滿的大平台!</Text>
<Text style={{ fontSize: 60, color: 'red' }}>帶給各位滿滿的大平台!</Text>
<Text style={{ fontSize: 60, color: 'blue' }}>帶給各位滿滿的大平台!</Text>
<Text style={{ fontSize: 60 }}>帶給各位滿滿的大平台!</Text>
<Text style={{ fontSize: 60, color: 'red' }}>帶給各位滿滿的大平台!</Text>
<Text style={{ fontSize: 60, color: 'blue' }}>帶給各位滿滿的大平台!</Text>
</ScrollView>
在滑動時,右側會出現滾動軸。(GIF 簡化不少影格,所以會比較不順)
更詳細的內容請參閱 ScrollView
的官方文件。
ListView
通常被用在呈現大量陣列資料時使用,不會一次 Render 所有的 Item,只會 Render 呈現在畫面上的 Item,可以改善單純使用 ScrollView
的效能問題。需要傳遞一個 Function 給 renderRow
,讓 ListView
知道怎麼去 Render 每一列。
ListView
的 dataSource
Prop 接一個 ListView.DataSource
,而產生它的時候要給一個回傳 Boolean 值的 rowHasChanged
Function,讓它可以判斷兩個 Row 是不是一樣的:
class ListViewBasics extends Component {
// Initialize the hardcoded data
constructor(props) {
super(props);
const ds = new ListView.DataSource({
rowHasChanged: (r1, r2) => r1 !== r2,
});
this.state = {
dataSource: ds.cloneWithRows([
'帶給各位!',
'滿滿的!',
'大平台!',
'帶給各位!',
'滿滿的!',
'大平台!',
'帶給各位!',
'滿滿的!',
'大平台!',
'帶給各位!',
'滿滿的!',
'大平台!',
])
};
}
render() {
return (
<View style={{ flex: 1, paddingTop: 22 }}>
<ListView
dataSource={this.state.dataSource}
renderRow={(rowData) => <Text style={{ fontSize: 60 }}>{rowData}</Text>}
/>
</View>
);
}
}
更詳細的內容請參閱 ListView
的官方文件。
這些互動相關的 Component 通常是使用者體驗是否良好的關鍵,在使用時也必須特別小心。